/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Yi Dev, Ltd. All Right Reserved.
 * @address:     http://Yi.tech
 * @date:        2019/5/20 20:57
 * @email:       https:yiyuery.github.io/NoteBooks
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.example.swagger.gen;

import com.example.common.ext.map.MapBuilder;
import com.example.swagger.common.base.AbstractSwaggerTransformPlugin;
import com.example.swagger.common.configuration.ApplicationYamlLoader;
import com.example.swagger.common.configuration.PropertiesConstant;
import com.example.swagger.common.enums.SwaggerSupportEnum;
import com.example.swagger.common.util.AsciidoctorHelper;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Language;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import lombok.extern.slf4j.Slf4j;
import org.asciidoctor.*;

import java.nio.file.Paths;

import static org.asciidoctor.Asciidoctor.Factory.create;

/**
 * <p>
 *
 * </p>
 *
 * @author Yi
 * @version v1.0.0
 * @date 2019-06-05 22:58
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2019-06-05
 * @modify reason: {方法名}:{原因}
 * ...
 */
@Slf4j
public class AsciiDocsGenerator extends AbstractSwaggerTransformPlugin {

    /**
     * API-DOCS 生成器
     */
    private Asciidoctor asciidoctor = create();

    @Override
    public void gen() {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(Language.EN)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();
        transform(config, SwaggerSupportEnum.ASCIIDOC);
    }

    /**
     * 输出文档
     */
    @Override
    public void apiDocs() {
        if (isCombine(SwaggerSupportEnum.ASCIIDOC)) {
            asciidoctor.convertFile(
                    Paths.get(ApplicationYamlLoader.getPropsByKey(
                            String.format(PropertiesConstant.EHANCE_CONFIG_COMBINE_GENERATOR_KEY, SwaggerSupportEnum.ASCIIDOC.getKey()),
                            String.class) + MarkupLanguage.ASCIIDOC.getFileNameExtensions().get(0)).toFile(),
                    customAttributes());
        } else {
            //多个 asciidoc 文件生成html/pdf
            asciidoctor.convertDirectory(
                    new AsciiDocDirectoryWalker(ApplicationYamlLoader.getPropsByKey(
                            String.format(PropertiesConstant.EHANCE_CONFIG_GENERATOR_KEY, SwaggerSupportEnum.ASCIIDOC.getKey()),
                            String.class)),
                    customAttributes());
        }

    }

    /**
     * 自定义文档属性
     * - 菜单
     * - 展示层级
     *
     * @return
     */
    private OptionsBuilder customAttributes() {
        OptionsBuilder options = OptionsBuilder.options();
        AttributesBuilder attributesBuilder = AttributesBuilder.attributes();
        setOptionsOnBuilder(options);
        AsciidoctorHelper.addAttributes(MapBuilder.<String,Object>maps()
                .put("toclevels","3")
                .put("toc","left")
                .build(),attributesBuilder);
        setAttributesOnBuilder(options,attributesBuilder);
        return options;
    }

    /**
     * 可选builder
     *
     * @param optionsBuilder
     */
    private static void setOptionsOnBuilder(OptionsBuilder optionsBuilder) {
        if(!isHtmlEnable()){
            log.warn("please enable html switch if you want transform and export html from asciidoc");
            return;
        }
        optionsBuilder
                //生成HTML
                .backend("html5")
                .safe(SafeMode.UNSAFE)
                .headerFooter(true)
                .mkDirs(true)
                .docType("book")
                //输出路径
                .toDir(Paths.get(ApplicationYamlLoader.getPropsByKey(
                        String.format(PropertiesConstant.EHANCE_CONFIG_EXPORT_PATH_KEY, SwaggerSupportEnum.ASCIIDOC.getKey()),
                        String.class)).toFile());
    }

    /**
     * 判断html导出是否开启
     * @return
     */
    private static boolean isHtmlEnable() {
        return ApplicationYamlLoader.getPropsByKey(
                String.format(PropertiesConstant.EHANCE_CONFIG_TRANSFORM_HTML_ENABLE_KEY, SwaggerSupportEnum.ASCIIDOC.getKey()),
                Boolean.class,Boolean.FALSE);
    }

    /**
     * 可选属性
     *
     * @param options
     * @param attributesBuilder
     */
    private static void setAttributesOnBuilder(OptionsBuilder options, AttributesBuilder attributesBuilder) {
        attributesBuilder.sourceHighlighter("coderay")
                .attributeMissing("skip")
                .imagesDir("./docs/resources/images")
                .attributeUndefined("drop-line");
        options.attributes(attributesBuilder);
    }
}
